<?php

namespace App\Services\Api;

use App\Exceptions\LogicException;
use App\Models\User;
use App\Utils\MiniprogramUtil;
use App\Utils\StringUtil;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class AuthService
{
    /**
     * @var User
     */
    protected $userModel;

    /**
     * UserAuthService constructor.
     * @param User $userModel
     */
    public function __construct(User $userModel)
    {
        $this->userModel = $userModel;
    }

    /**
     * 小程序登录
     * @param array $data 登录数据
     * @return array
     * @throws LogicException
     */
    public function miniLogin(array $data): array
    {
        // 验证必要参数
        if (empty($data['code'])) {
            throw new LogicException('登录凭证不能为空');
        }

        try {
            // 获取session信息
            $result = MiniprogramUtil::getInstance()->getSession($data['code']);

            // 获取openid
            $openid = $result['openid'] ?? '';
            if (empty($openid)) {
                throw new LogicException('获取用户标识失败');
            }

            $user = $this->handleUserInfo($openid, $result, $data);

            // 生成token
            $token = Auth::guard('api')->login($user);

            return [
                'token' => $token,
                'expires_in' => auth('api')->factory()->getTTL() * 60,
                'user' => [
                    'id' => $user['id'],
                    'nickname' => $user['nickname'] ?? '',
                    'avatar' => $user['avatar'] ?? ''
                ]
            ];
        } catch (\Exception $e) {
            if ($e instanceof LogicException) {
                throw $e;
            }
            Log::error('小程序登录异常', ['code' => $data['code'], 'error' => $e->getMessage()]);
            throw new LogicException('登录失败：' . $e->getMessage());
        }
    }

    /**
     * 用户登录
     * @param array $credentials 登录数据
     * @return array
     * @throws LogicException
     */
    public function login(array $credentials): array
    {
        // $credentials['password'] = $credentials['mobile'];
        if (!($token = Auth::guard('api')->attempt($credentials))) {
            throw new LogicException('用户不存在');
        }

        return [
            'token' => $token,
            'expires_in' => auth('api')->factory()->getTTL() * 60,
        ];
    }

    /**
     * 刷新token
     * @return array
     */
    public function refresh(): array
    {
        return [
            'token' => Auth::guard('api')->refresh(),
            'token_type' => 'bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ];
    }

    /**
     * 处理用户信息
     * @param string $openid 用户openid
     * @param array $result 小程序session信息
     * @param array $data 用户提交的数据
     * @return User
     */
    private function handleUserInfo(string $openid, array $result, array $data)
    {
        // 查询用户是否存在
        $user = $this->userModel->where('openid', $openid)->select(['id', 'nickname', 'avatar'])->first();

        // 用户信息
        $userData = [
            'openid' => $openid,
        ];

        // 用户不存在则创建
        if (empty($user)) {
            $userData['nickname'] = 'User_' . StringUtil::random(6, StringUtil::TYPE_NUMBER);
            $id = $this->userModel->create($userData);
            $user = $this->userModel->where('id', $id)->select(['id', 'nickname', 'avatar'])->first();
        }

        return $user;
    }

    /**
     * 获取个人信息
     * @return array
     */
    public function me()
    {
        $user = auth('api')->user();
        return [
            'token' => auth('api')->getToken()->get(),
            'expires_in' => auth('api')->factory()->getTTL() * 60,
            'user' => [
                'id' => $user['id'],
                'nickname' => $user['nickname'] ?? '',
                'avatar' => $user['avatar'] ?? ''
            ],
        ];
    }
}
